#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//注意:当close(1)时，下面代码看不到屏幕上输出"open fd:1"的原因是printf是向stdout中输出的,stdout对应的就是文件描述符为1(fd=1),所以printf向stdout输出,其实就是向文件描述符为1所指向的文件输出,但此时文件描述符为1的文件不再是显示器,而是log.txt,所以数据不会在显示器上被显示,而是会写入到log.txt文件中,但要刷新冲存区,使缓冲区中的数据输出到对应文件中去
int main()
{
    //close(0);
    //close(2);
    //close(1);//当关闭1时,无法输出到显示屏的原因是该进程默认打开的文件描述符1所对应的标准输出stdout所指向的显示屏文件(设备)被关闭,而printf()是向stdout(标准输出对应的文件描述符fd为1)指向的文件输出的,所以该进程内printf()无法输出到显示屏上,而是会输出到log.txt文件中,但要刷新缓存区,立刻将缓冲区的数据写入到对应的文件中
    //设置权限掩码
    umask(2);
    //打开文件
    //输出重定向
    //int fd = open("log.txt" , O_WRONLY | O_CREAT | O_TRUNC , 0666);//没有指明路径,默认在当前进程运行的工作路径下    
    //追加重定向
    //int fd = open("log.txt" , O_WRONLY | O_CREAT | O_APPEND , 0666);//没有指明路径,默认在当前进程运行的工作路径下    
    //输入重定向
    int fd = open("log.txt" , O_RDONLY);//没有指明路径,默认在当前进程运行的工作路径下    
    if(fd < 0)//打开/创建文件失败
    {
        perror("open");
        return 1;
    }
   
    //用dup2(int oldfd , int newfd)实现重定向-->用oldfd对应的内容覆盖newfd对应的空间
    //dup2(fd , 1);//文件描述符fd对应的内容覆盖文件描述符1对应的空间   
    //dup2(fd , 1);//输出,追加的重定向
    dup2(fd , 0);//输入重定向

    //从stdin中读取
    char line[64];

    while(1)
    {
        printf(">");
        if(fgets(line , sizeof(line) , stdin) == NULL) break;//如果从缓存区按行读取失败(无数据可读),返回NULL
        printf("%s",line);
    }
    


    //输出文件描述符
    //printf("open fd:%d\n",fd);//printf-->stdout
    //fprintf(stdout,"open fd:%d\n",fd);//fprintf-->stdout 
    
    //刷新缓冲区
    fflush(stdout);
    //关闭文件
    close(fd);

    return 0;
}
